#include "WoodBox.h"
#include "Physics.h"
#include "Time.h"
#include "Camera.h"
#include "EmitterManager.h"

// Constructor
WoodBox::WoodBox(void)
{
	this->objectID = "Wood Box";
	this->SetCanBeGrappled(false);
	this->canFall = true;
	this->SetCoolRate(1.0f);

	burnTime = 3.0f;
	resetBurnTime = 3.0f;
	isBurning = false;

	//this->curTemp = 0.0f;

	//Create Fire Emitters
	//EmitterManager::GetInstance()->Load(tag, "box_fire.xml", false, positionX, positionY);

	return;
}

// Destructor
WoodBox::~WoodBox(void)
{
}

void WoodBox::ResetToCheckPoint(void)
{

}

void WoodBox::ResetToStart(void)
{

}

// Update
//	- The override of GameObject's Update method.
//	- Updates the wood box.
void WoodBox::Update(float deltaTime)
{
	//fall every frame regardless of gravity
	//if(canFall == true)
	this->positionY += Physics::GetGravity() * deltaTime;

	Physics::UpdateColRect(hitBox, (int)positionX, (int)positionY);

	// Update the Fire Emitter
	EmitterManager::GetInstance()->GetEmitter(tag)->SetPosX(positionX - CSGD_TextureManager::GetInstance()->GetTextureWidth(imageID) * 0.5f - 8);
	EmitterManager::GetInstance()->GetEmitter(tag)->SetPosY(positionY - CSGD_TextureManager::GetInstance()->GetTextureHeight(imageID) * 0.5f - 8);

	// If the box's temperature excedes its maximum temperature, BURN IT!!!!!
	if(CurTemp() >= MaxTemp())
	{
		isBurning = true;
	}

	// Is the box burning?
	if(isBurning == true)
	{
		burnTime -= deltaTime;
		EmitterManager::GetInstance()->GetEmitter(tag)->SetActive(true);
		EmitterManager::GetInstance()->GetEmitter(tag)->Update(deltaTime);
	}

	// Has the burn time expired.
	if(burnTime <= 0.0f)
	{
		isActive = false;
		isBurning = false;
		EmitterManager::GetInstance()->GetEmitter(tag)->SetActive(false);
	}

	//Check below the box. If there is nothing below the box apply gravity
	float BoxHeight = (float)hitBox.bottom - hitBox.top;
	float BoxWidth = (float)hitBox.right - hitBox.left; 

	//Calculate Center
	tVector2D BoxCenter = { BoxWidth * 0.5f + hitBox.left, hitBox.bottom + 1.0f };

	HeatPhysics::Update(deltaTime);
}

// Render
//	- The override of GameObject's Render method.
//	- Renders the wood box.
void WoodBox::Render(void) const
{
	// Don't render if inactive.
	if(isActive == false)
		return;

	CSGD_TextureManager::GetInstance()->Draw(imageID, 
		(int)(positionX - Camera::GetInstance()->OffsetX()),
		(int)(positionY - Camera::GetInstance()->OffsetY()));

	if(isBurning)
		EmitterManager::GetInstance()->GetEmitter(tag)->Render();

	////Render hitbox over box for temperature color
	RECT box = GetHitBox();
	box.left = (int)(box.left - Camera::GetInstance()->OffsetX());
	box.right = (int)(box.right - Camera::GetInstance()->OffsetX());
	box.bottom = (int)(box.bottom - Camera::GetInstance()->OffsetY());
	box.top = (int)(box.top - Camera::GetInstance()->OffsetY());
	CSGD_Direct3D::GetInstance()->DrawRect(box,GetColorFromTemp());

}

// HandleCollision
//	- The override of GameObject's HandleCollision method.
//	- Handles collisions for the wood box.
void WoodBox::HandleCollision(GameObject& other, CollisionInfo& info)
{
	// Don't handle collision if inactive.
	if(isActive == false)
		return;

	//Physics::UpdateColRect(hitBox, (int)positionX, (int)positionY);

	//Object that got hit
	LinecastInfo * ObjectHit = nullptr;

	//Box Width
	int BoxWidth = hitBox.right - hitBox.left;
	int BoxHeight = hitBox.bottom - hitBox.top;

	//Vectors
	tVector2D LeftCenterCheck = {hitBox.left + BoxWidth + 1.0f, hitBox.top + BoxHeight * 0.5f};
	tVector2D RightCenterCheck = {hitBox.left - 1.0f, hitBox.top + BoxHeight * 0.5f};

	tVector2D CheckRight = {1,0};
	tVector2D CheckLeft = {-1,0};


	//Able to push the box
	if(other.GetObjectID() == "Metal Box" || other.GetObjectID() == "Wood Box" || other.GetObjectID() == "Radiation Barrel")
	{
		int amtToMove;
		switch( info.Side )
		{
		case LEFT:
			amtToMove = info.Overlap.right - info.Overlap.left;
			other.Push( info.Side, amtToMove );
			break;
		case RIGHT:
			amtToMove = info.Overlap.right - info.Overlap.left;
			other.Push( info.Side, amtToMove );
			break;
		case TOP:
			amtToMove = info.Overlap.right - info.Overlap.left;
			other.Push( info.Side, amtToMove );
			break;
		case BOTTOM:
			amtToMove = info.Overlap.right - info.Overlap.left;
			other.Push( info.Side, amtToMove );
			break;
		}
	}

	if( other.GetTag() == "floor" || other.GetObjectID() == "Button" )
	{
		canFall = false;
	}

	if( other.GetObjectID() == "Wood Box" || other.GetObjectID() == "Metal Box")
	{
		canFall = false;
	}

	if( other.GetObjectID() == "thermo object" )
	{
		this->ApplyHeat(2.0f);
	}

}

// SetBurnTime
//	- Sets the time in seconds that the box will burn before being destroyed.
void WoodBox::SetBurnTime(float time)
{
	burnTime = time;
	resetBurnTime = time;
}


int WoodBox::Push(CollisionSide side, int amtToMove)
{
	LinecastInfo castInfo;
	tVector2D castStart;
	tVector2D castStartVert;
	tVector2D direction;
	switch(side)
	{
	case LEFT:
		castStart.fX = (float)hitBox.right;
		castStart.fY = (float)positionY + (hitBox.bottom - hitBox.top)/2;
		direction.fX = 1.0f;
		direction.fY = 0.0f;
		if(Physics::LineCast(castInfo, (float)amtToMove, castStart,direction, "Wood Box"))
		{
			int amtCanMove = (int)castInfo.Distance;
			positionX += amtCanMove + 4;
			return amtCanMove;
		}
		else
		{
			positionX += amtToMove + 4;
			return amtToMove;
		}
		break;
	case RIGHT:
		castStart.fX = (float)hitBox.left;
		castStart.fY = positionY + (hitBox.bottom - hitBox.top)/2;
		direction.fX = -1;
		direction.fY = 0;
		if(Physics::LineCast(castInfo, (float)amtToMove, castStart,direction, "Wood Box"))
		{
			int amtCanMove = (int)castInfo.Distance;
			positionX -= amtCanMove + 4;
			return amtCanMove;
		}
		else
		{
			positionX -= amtToMove + 4;
			return amtToMove;
		}
		break;
	case TOP:
		castStart.fX = positionX + (hitBox.right - hitBox.left);
		castStartVert.fX = positionX;
		castStart.fY = (float)castStartVert.fY = (float)hitBox.top;
		direction.fX = 0;
		direction.fY = -1;
		if(Physics::LineCast(castInfo, (float)amtToMove, castStart,direction, "Wood Box") || Physics::LineCast(castInfo, (float)amtToMove, castStartVert,direction, "Wood Box"))
		{
			int amtCanMove = (int)castInfo.Distance;
			positionY += amtCanMove + 1;
			return amtCanMove;
		}
		else
		{
			positionY += amtToMove + 1;
			return amtToMove;
		}
		break;
	case BOTTOM:
		//castStart.fX = positionX + (hitBox.right - hitBox.left);
		//castStartVert.fX = positionX;
		//castStart.fY = castStartVert.fY = hitBox.bottom;
		//direction.fX = 0;
		//direction.fY = 1;
		//if(Physics::LineCast(castInfo, amtToMove, castStart,direction, "Metal Box") || Physics::LineCast(castInfo, amtToMove, castStartVert,direction, "Metal Box"))
		//{
		//	int amtCanMove = castInfo.Distance;
		//	positionY += amtCanMove + 4;
		//	return amtCanMove;
		//}
		//else
		{
			positionY -= (float)amtToMove+ 1;
			return amtToMove;
		}
		break;
	}
	return 0;
}
